package com.cloudkinto.service.regular.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cloudkinto.common.BeanConvert;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.dao.CompanyDao;
import com.cloudkinto.dao.ProductDao;
import com.cloudkinto.entity.*;
import com.cloudkinto.dao.PlatformOrderSplitRegularDao;
import com.cloudkinto.service.platform.PlatformStoreService;
import com.cloudkinto.service.regular.PlatformOrderSplitRegularInfoService;
import com.cloudkinto.service.regular.PlatformOrderSplitRegularService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;

import com.cloudkinto.utils.BeanCopierUtils;
import com.cloudkinto.vo.product.ProductSkuVo;
import com.cloudkinto.vo.regular.*;
import com.cloudkinto.vo.regular.split.PlatRegularSplitAddReq;
import com.cloudkinto.vo.regular.split.PlatRegularSplitInfoAddReq;
import com.cloudkinto.vo.regular.split.PlatRegularSplitUpdateReq;
import com.cloudkinto.vo.regular.split.PlatSplitRegularPageDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  service实现类
 * </p>
 * @author hua
 * @since 2025-03-10
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)//事务回滚
public class PlatformOrderSplitRegularServiceImpl extends ServiceImpl<PlatformOrderSplitRegularDao, PlatformOrderSplitRegularDo> implements PlatformOrderSplitRegularService {

    private final CompanyDao companyDao;
    private final PlatformOrderSplitRegularInfoService platformOrderSplitRegularInfoService;
    private final ProductDao productDao;
    private final PlatformStoreService platformStoreService;



    @Override
    public SingleResult addInit() {
        return SingleResult.success("");
    }


    public void check(String regularName, Long id, Long companyId) {
        if (StringUtils.isBlank(regularName)) throw new BizException(SysConstant.Add_Name_Empty);
        //名称不能重复
        PlatformOrderSplitRegularDo et = baseMapper.selectOne(new LambdaQueryWrapper<PlatformOrderSplitRegularDo>()
                .ne(id != null, PlatformOrderSplitRegularDo::getId, id)
                .eq(PlatformOrderSplitRegularDo::getRegularName, regularName)
                .eq(PlatformOrderSplitRegularDo::getCompanyId, companyId));
        if (et != null) throw new BizException(SysConstant.Add_Name_Same);
    }

    @Override
    public Object add(PlatRegularSplitAddReq req, Long userId, Long companyId) {
        CompanyDo companyDo = companyDao.selectById(companyId);
        if (companyDo == null) return null;
        this.check(req.getRegularName(), null, companyId);
        PlatformOrderSplitRegularDo entityDo = new PlatformOrderSplitRegularDo();
        BeanUtils.copyProperties(req, entityDo);
        entityDo.setCompanyId(companyId);
        entityDo.setTenantId(companyDo.getTenantId());
        baseMapper.insert(entityDo);
        entityDo.setSort(entityDo.getId());
        baseMapper.updateById(entityDo);
        this.insertRuleInfos(req.getList(), entityDo.getId());
        return entityDo.getId();
    }

    public void insertRuleInfos(List<PlatRegularSplitInfoAddReq> list, Long id) {
        List<PlatformOrderSplitRegularInfoDo> regularInfoDos = BeanConvert.INSTANCE.platformOrderSplitRegularInfoDo(list);
        for (int i = 0; i < regularInfoDos.size(); i++) {
            PlatformOrderSplitRegularInfoDo regularInfoDo = regularInfoDos.get(i);
            regularInfoDo.setRuleId(id);
        }
        platformOrderSplitRegularInfoService.saveBatch(regularInfoDos);
    }


    @Override
    public SingleResult updateInit(Long id) {
        return SingleResult.success("");
    }



    public Object update(PlatRegularSplitUpdateReq req, Long userId, Long companyId) {
        this.check(req.getRegularName(), req.getId(), companyId);
        PlatformOrderSplitRegularDo entityDo = baseMapper.selectById(req.getId());
        if (entityDo == null || !Objects.equals(companyId, entityDo.getCompanyId())) return null;
        BeanUtils.copyProperties(req, entityDo);
        baseMapper.updateById(entityDo);
        platformOrderSplitRegularInfoService.lambdaUpdate().eq(PlatformOrderSplitRegularInfoDo::getRuleId, entityDo.getId())
                .set(PlatformOrderSplitRegularInfoDo::getDeleteBy, userId)
                .set(PlatformOrderSplitRegularInfoDo::getDeleteTime, new Date())
                .set(PlatformOrderSplitRegularInfoDo::getDeleteFlag, 1).update();
        this.insertRuleInfos(req.getList(), entityDo.getId());
        return entityDo.getId();
    }

    @Override
    public int delete(List<Long> ids, Long userId, Long companyId) {
        if (ids == null || ids.isEmpty()) return 0;
        boolean update = this.lambdaUpdate().in(PlatformOrderSplitRegularDo::getId, ids).eq(PlatformOrderSplitRegularDo::getCompanyId, companyId)
                .set(PlatformOrderSplitRegularDo::getDeleteFlag, 1).update();
        platformOrderSplitRegularInfoService.lambdaUpdate().in(PlatformOrderSplitRegularInfoDo::getRuleId, ids)
                .set(PlatformOrderSplitRegularInfoDo::getDeleteBy, userId)
                .set(PlatformOrderSplitRegularInfoDo::getDeleteTime, new Date())
                .set(PlatformOrderSplitRegularInfoDo::getDeleteFlag, 1).update();
        return update ? 1 : 0;
    }


    @Override
    public PlatRegularSplitUpdateReq detail(Long id) {
        PlatformOrderSplitRegularDo entityDo = baseMapper.selectById(id);
        PlatRegularSplitUpdateReq res = new PlatRegularSplitUpdateReq();
        BeanUtils.copyProperties(entityDo, res);
        List<PlatformOrderSplitRegularInfoDo> regularInfoDos = platformOrderSplitRegularInfoService.lambdaQuery().eq(PlatformOrderSplitRegularInfoDo::getRuleId, id).list();
        List<PlatRegularSplitInfoAddReq> list = BeanCopierUtils.listCopyMapper(regularInfoDos, PlatformOrderSplitRegularInfoDo.class, PlatRegularSplitInfoAddReq.class);
        res.setList(list);
        List<String> productIds = regularInfoDos.stream().filter(i -> StaticDict.Regular_Split_ChildType.Five.getValue().equals(i.getChildType()))
                .map(PlatformOrderSplitRegularInfoDo::getStartValue).collect(Collectors.toList());
        if (!productIds.isEmpty()) {
            List<ProductDo> productDos = productDao.selectBatchIds(productIds);
            List<ProductSkuVo> products = BeanCopierUtils.listCopyMapper(productDos, ProductDo.class, ProductSkuVo.class);
            res.setProducts(products);
        }
        List<String> splitProductIds = regularInfoDos.stream().filter(i -> StaticDict.Regular_Split_ChildType.Twelfth.getValue().equals(i.getChildType()))
                .map(PlatformOrderSplitRegularInfoDo::getStartValue).collect(Collectors.toList());

        if (!splitProductIds.isEmpty()) {
            List<ProductDo> productDos = productDao.selectBatchIds(splitProductIds);
            List<ProductSkuVo> products = BeanCopierUtils.listCopyMapper(productDos, ProductDo.class, ProductSkuVo.class);
            res.setSplitProducts(products);
        }
        return res;
    }

    @Override
    public SingleResult pageInit(Long companyId) {
        Map<String, Object> map = new HashMap<>();
        map.put("moduleTypeList", StaticDict.getRegular_Split_ModuleType());
        map.put("childTypeList", StaticDict.getRegularSplitChildType());
        map.put("storeList", platformStoreService.getList(companyId));
        map.put("platformCode", StaticDict.getStore_PlatformCode());
        return SingleResult.success(map);
    }

    @Override
    public List<PlatSplitRegularPageDto> getList(Map<String, Object> map) {
        List<PlatSplitRegularPageDto> list = baseMapper.listPage(map);
        return list;
    }

    @Override
    public PageResult getListPage(Map<String, Object> map) {
        IPage<PlatSplitRegularPageDto> page = pageInit(map);
        page = baseMapper.listPage(page, map);
        PageResult result = new PageResult(page.getRecords(), (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        return result;
    }

    @Override
    public void updateSort(PlatRegularSortReq req, Long userId, Long companyId) {
        List<Long> ids = req.getIds();
        if (ids == null || ids.isEmpty()) return;
        List<PlatformOrderSplitRegularDo> list = this.lambdaQuery().eq(PlatformOrderSplitRegularDo::getCompanyId, companyId)
                .in(PlatformOrderSplitRegularDo::getId, ids).list();
        Map<Long, Long> collect = list.stream().collect(Collectors.toMap(PlatformOrderSplitRegularDo::getId, PlatformOrderSplitRegularDo::getSort));

        List<Long> values = new ArrayList<>(collect.values());
        values.sort(Collections.reverseOrder());
        if (ids.size() != values.size()) return;
        for (int i = 0; i < ids.size(); i++) {
            this.lambdaUpdate().eq(PlatformOrderSplitRegularDo::getId, ids.get(i))
                    .set(PlatformOrderSplitRegularDo::getUpdateBy, userId)
                    .set(PlatformOrderSplitRegularDo::getUpdateTime, new Date())
                    .set(PlatformOrderSplitRegularDo::getSort, values.get(i)).update();
        }
    }

    @Override
    public void updateRegularStatus(PlatRegularStatusReq req, Long userId, Long companyId) {
        List<Long> ids = req.getIds();
        if (ids == null || ids.isEmpty()) return;
        this.lambdaUpdate().in(PlatformOrderSplitRegularDo::getId, ids)
                .eq(PlatformOrderSplitRegularDo::getCompanyId, companyId)
                .ne(PlatformOrderSplitRegularDo::getStatus, req.getStatus())
                .set(PlatformOrderSplitRegularDo::getUpdateBy, userId)
                .set(PlatformOrderSplitRegularDo::getUpdateTime, new Date())
                .set(PlatformOrderSplitRegularDo::getStatus, req.getStatus()).update();
    }


    private IPage<PlatSplitRegularPageDto> pageInit(Map<String, Object> map) {
        IPage<PlatSplitRegularPageDto> page = new Page<>();
        page.setSize(map.get("pageSize") != null ? Long.parseLong(map.get("pageSize").toString()) : 10);
        page.setCurrent(map.get("current") != null ? Long.parseLong(map.get("current").toString()) : 1);
        return page;
    }



}
